(function() {
    var A = YAHOO.util.CustomEvent;
    IMO.Ajax = function(D, C, B) {
        this.host = C;
        this.ssid = D;
        this.client = B;
        this.subsystems = {};
        this.experiencing_network_problems = false;
        this.ev_network_health = new A("network_health");
        this.dispatcher = new IMO.Dispatcher(D, C, B);
        this.dispatcher.ev_message.subscribe(this.handle_message, this, true);
        this.dispatcher.ev_failure_dispatcher.subscribe(this.handle_failure, this, true)
    };
    IMO.Ajax.prototype = {
        NAME: "IMO.Ajax",
        register_subsystem: function(B) {
            var C = new IMO.MessageWrapper(this.ssid, B, this.dispatcher);
            this.subsystems[B] = C;
            return C
        },
        handle_activity: function(C, B, D) {
            console.log("firing network reconnected");
            this.ev_network_health.fire("network_reconnected");
            this.dispatcher.ev_activity.unsubscribe(this.handle_activity, this);
            this.experiencing_network_problems = false
        },
        handle_message: function(C, B, F) {
            var D = B[0];
            var G = D.from["system"];
            var E = this.subsystems[G];
            if (E) {
                E.evEvent.fire(D.data)
            } else {
                YAHOO.log("unknown subsystem:" + G)
            }
        },
        reset: function(C) {
            console.log("resetting dispatcher");
            this.ssid = C;
            for (var B in this.subsystems) {
                var D = this.subsystems[B];
                D.ssid = C
            }
            this.dispatcher.ssid = C;
            this.dispatcher.reset()
        },
        pause: function() {
            console.log("stopping polling");
            this.dispatcher.stop_all_timers()
        },
        handle_failure: function(E, D, F) {
            var C = D[0];
            var B = D[1];
            var G = D[2];
            if (C > 2) {
                console.log("firing network problem");
                this.ev_network_health.fire("network_problem")
            }
            if (!this.experiencing_network_problems) {
                this.dispatcher.ev_activity.subscribe(this.handle_activity, this, true)
            }
            this.experiencing_network_problems = true
        }
    };
    IMO.MessageWrapper = function(D, C, B) {
        this.ssid = D;
        this.subsystem = C;
        this.dispatcher = B;
        this.evEvent = new A("events");
        this.evFailure = new A("failure")
    };
    IMO.MessageWrapper.prototype = {
        execute_rpc: function(D, C) {
            var B = {};
            B.data = {
                method: D,
                data: C
            };
            B.to = {
                system: this.subsystem
            };
            B.from = {
                system: "client",
                ssid: this.ssid
            };
            this.dispatcher.forward_to_server(B)
        }
    }
}());